﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AzureInterop.Windows.Controls
{
	internal class AzureTreeViewItemHelper
	{
		private const string DUMMY_ITEM = "7466 dummy item 7466";

		// A dummy item is added in order to force the + icon to appear beside the current item.
		internal static void AddDummyItem(System.Windows.Controls.ItemCollection items)
		{
			System.Diagnostics.Debug.Assert(null != items);
			System.Diagnostics.Debug.Assert(0 == items.Count);

			items.Add(DUMMY_ITEM);
		}

		internal static bool HasDummyItem(System.Windows.Controls.ItemCollection items)
		{
			System.Diagnostics.Debug.Assert(null != items);
			
			bool retval = false;
			if (0 < items.Count)
			{
				retval = items[0].Equals(DUMMY_ITEM);
			}
			
			return retval; 
		}

		internal static void RemoveDummyItem(System.Windows.Controls.ItemCollection items)
		{
			if (null != items && HasDummyItem(items))
			{
				System.Diagnostics.Debug.Assert(items[0].Equals(DUMMY_ITEM));
				items.Clear();
			}
		}
	}

	public class AzureTreeViewItem : System.Windows.Controls.TreeViewItem
	{
		public AzureTreeViewItem() : base()
		{
			Expanded += new System.Windows.RoutedEventHandler(AzureTreeViewItem_Expanded);
		}

		#region Public factory
		public static AzureTreeViewItem CreateTreeViewItem(object itemObject)
		{
			AzureTreeViewItem tvi = new AzureTreeViewItem();
			tvi.Tag = itemObject;

			Type azType = tvi.Tag.GetType();
			if (azType.Equals(typeof(Microsoft.WindowsAzure.CloudStorageAccount))
				|| azType.Equals(typeof(Microsoft.WindowsAzure.StorageClient.CloudBlobContainer))
				|| azType.Equals(typeof(Microsoft.WindowsAzure.StorageClient.CloudBlobDirectory)))
			{
				// Add dummy item so this item is expandable
				AzureTreeViewItemHelper.AddDummyItem(tvi.Items);
			}

			Microsoft.WindowsAzure.StorageClient.IListBlobItem blobItem = tvi.Tag as Microsoft.WindowsAzure.StorageClient.IListBlobItem;
			if (null != blobItem)
			{
				tvi.Header = AzureInterop.CloudBlobHelper.GetName(blobItem);
				tvi.ToolTip = blobItem.Uri.ToString();
			}
			else
			{
				Microsoft.WindowsAzure.StorageClient.CloudBlobContainer container = tvi.Tag as Microsoft.WindowsAzure.StorageClient.CloudBlobContainer;
				if (null != container)
				{
					tvi.Header = container.Name;
					tvi.ToolTip = container.Uri.ToString();
				}
				else
				{
					System.Diagnostics.Debug.Assert(tvi.Tag.GetType().Equals(typeof(Microsoft.WindowsAzure.CloudStorageAccount)));
					tvi.Header = ((Microsoft.WindowsAzure.CloudStorageAccount)tvi.Tag).Credentials.AccountName;
					tvi.ToolTip = ((Microsoft.WindowsAzure.CloudStorageAccount)tvi.Tag).BlobEndpoint;
				}
			}
			return tvi;
		}

		#endregion

		#region TreeViewItem Event handlers
		void AzureTreeViewItem_Expanded(object sender, System.Windows.RoutedEventArgs e)
		{
			AzureTreeViewItem tvi = sender as AzureTreeViewItem;
			System.Diagnostics.Debug.Assert(null != tvi);
			System.Diagnostics.Debug.Assert(null != tvi.Tag);
			
			// If the expanded item has a dummy item, then populate items from Azure
			if (!tvi.HasItems || AzureTreeViewItemHelper.HasDummyItem(tvi.Items))
			{
				// First, remove the dummy item
				AzureTreeViewItemHelper.RemoveDummyItem(tvi.Items);

				// Does the expanded item represent a container?
				Microsoft.WindowsAzure.StorageClient.CloudBlobContainer container = tvi.Tag as Microsoft.WindowsAzure.StorageClient.CloudBlobContainer;
				if (null != container)
				{
					PopulateItem(tvi, container);
				}
				else
				{
					Microsoft.WindowsAzure.StorageClient.CloudBlobDirectory dir = tvi.Tag as Microsoft.WindowsAzure.StorageClient.CloudBlobDirectory;
					if (null != dir)
					{
						PopulateItem(tvi, dir);
					}
					else
					{
						// Does the expanded item represent a storage account?
						Microsoft.WindowsAzure.CloudStorageAccount acct = tvi.Tag as Microsoft.WindowsAzure.CloudStorageAccount;
						if (null != acct)
						{
							PopulateItem(tvi, acct);
						}
					}
				}
			}

			e.Handled = true;
		}
		#endregion

		#region Private methods
		private static void PopulateItem(AzureTreeViewItem tvi, Microsoft.WindowsAzure.StorageClient.CloudBlobContainer container)
		{
			// get blobs from Azure
			foreach (Microsoft.WindowsAzure.StorageClient.IListBlobItem blobItem in container.ListBlobs())
			{
				tvi.Items.Add(CreateTreeViewItem(blobItem));
			}
		}

		private static void PopulateItem(AzureTreeViewItem tvi, Microsoft.WindowsAzure.StorageClient.CloudBlobDirectory directory)
		{
			// get blobs from Azure
			foreach (Microsoft.WindowsAzure.StorageClient.IListBlobItem blobItem in directory.ListBlobs())
			{
				tvi.Items.Add(CreateTreeViewItem(blobItem));
			}
		}

		private static void PopulateItem(AzureTreeViewItem tvi, Microsoft.WindowsAzure.CloudStorageAccount acct)
		{
			// get containers from Azure
			Microsoft.WindowsAzure.StorageClient.CloudBlobClient client = new Microsoft.WindowsAzure.StorageClient.CloudBlobClient(acct.BlobEndpoint, acct.Credentials);
			foreach (Microsoft.WindowsAzure.StorageClient.CloudBlobContainer c in client.ListContainers())
			{
//				tvi.Items.Add(CreateTreeViewItem(c);
				AzureTreeViewItem tviContainer = new AzureTreeViewItem();

				tviContainer.Tag = c;
				tviContainer.Header = c.Name;
				tviContainer.ToolTip = c.Uri.ToString();
				AzureTreeViewItemHelper.AddDummyItem(tviContainer.Items);
				tvi.Items.Add(tviContainer);
			}
		}
		#endregion
	}
}
